from tkinter import *
from tkinter import messagebox
import requests
import json
from bs4 import BeautifulSoup
from urllib import request
from urllib import parse
import re
root = Tk()

def getWeather(code):
    r = requests.get("http://www.weather.com.cn/weather/{}.shtml".format(code))
    #print(r.content.decode("utf-8"))
    soup = BeautifulSoup(r.content.decode("utf-8"),'lxml')
    print(soup)
    #css选择器
    ul = soup.select('.t.clearfix')
    array_li = ul[0].select('li')
    weather_data = []
    '''
    <ul class="t clearfix">
    <li class="sky skyid lv4 on">
    <h1>20日（今天）</h1>
    <big class="png40 d53"></big>
    <big class="png40 n53"></big>
    <p class="wea" title="霾">霾</p>
    <p class="tem">
    <span>7</span>/<i>-5℃</i>
    </p>
    <p class="win">
    <em>
    <span class="SE" title="东南风"></span>
    <span class="N" title="北风"></span>
    </em>
    <i>&lt;3级</i>
    </p>
    <div class="slid"></div>
    </li>
    <li class="sky skyid lv4">
    <h1>21日（明天）</h1>
    <big class="png40 d00"></big>
    <big class="png40 n01"></big>
    <p class="wea" title="晴转多云">晴转多云</p>
    <p class="tem">
    <span>10</span>/<i>-3℃</i>
    </p>
    <p class="win">
    <em>
    <span class="SW" title="西南风"></span>
    <span class="SW" title="西南风"></span>
    </em>
    <i>&lt;3级</i>
    </p>
    <div class="slid"></div>
    </li>
    '''
    for li in array_li:
        day = li.select('h1')[0].string#日期
        array_p = li.select('p')
        wea = array_p[0].string#天气
        if array_p[1].span is None:
            tem1 = ""
        else:
            danwei = '℃'
            tem1 = array_p[1].span.string+str(danwei)#高温度
        if array_p[1].i is None:
            tem2 = ""
        else:
            tem2 = array_p[1].i.string#低温度
        em = array_p[2].em#风向标签在第三个P标签里面
        if len(em.select('span')) == 2:
            win1 = em.select('span')[0].attrs['title']#风向
            win2 = em.select('span')[1].attrs['title']#风向
        elif len(em.select('span')) == 1:
            win1 = em.select('span')[0].attrs['title']  # 风向
            win2 = ""
        level = array_p[2].i.string
        weather_data.append({"day":day,"wea":wea,"temh":tem1,"teml":tem2,"win":win1+" "+win2,"level":level})

    return weather_data

def getCityCode(city):
    cityname = {'cityname':city}
    #将传进的城市名转化成urlencode编码
    cityname = parse.urlencode(cityname)
    url = 'http://toy1.weather.com.cn/search?callback=success_jsonpCallback&_=1545212777137&'
    full_url = url+str(cityname)
    r = requests.get(full_url).text
    #在Python的正则表达式中，有一个参数为re.S。它表示“.”（不包含外侧双引号，下同）的作用扩展到整个字符串，包括“\n”
    pattern = re.compile(r'success_jsonpCallback\((.*?)\)', re.S)
    #search函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回，如果字符串没有匹配，则返回None。
    if pattern.search(r).group(1) == "[]":
        return None
    else:
        #print(pattern.search(r).group(1))
        #[{"ref":"101120401~shandong~德州~Dezhou~德州~Dezhou~534~253000~DZ~山东"},{"ref":"101271605007~sichuan~德州镇~dezhouzhen~德昌~dechang~0834~615500~sichuan~四川"}]
        #json.loads()函数是将json格式数据转换为字典
        return json.loads(pattern.search(r).group(1))[0]['ref'].split("~")[0]

def main():
    # 输入窗口
    root.title('天气查询')  # 窗口标题
    Label(root, text='请输入城市').grid(row=0, column=0)  # 设置标签并调整位置
    enter = Entry(root)  # 输入框
    enter.grid(row=0, column=1, padx=20, pady=20)  # 调整位置
    enter.delete(0, END)  # 清空输入框
    #enter.insert(0, '北京')  # 设置默认文本
    #enter_text = enter.get()#获取输入框的内容

    running = 1

    def get_weather_data():  # 将分析的网站数据传递进去
        city_name = enter.get()  # 获取输入框的内容
        code = getCityCode(city_name)#获取城市编码
        #print(code)
        # 如果不存在这个城市
        if code == None:
            print(messagebox.askokcancel("错误提示", "你输入的城市名有误，或者天气中心未收录你所在城市"))
        else:
            show_data(getWeather(code), city_name)

    def show_data(weather_data, city_name):  # 显示数据
        forecast = weather_data  # 获取数据块
        root1 = Tk()  # 副窗口
        root1.geometry('1200x280')  # 修改窗口大小
        root1.title(city_name + '天气状况')  # 副窗口标题

        # 设置日期列表
        for i in range(7):  # 将每一天的数据放入列表中
            LANGS = [(forecast[i].get('day'), '日期'),
                     (forecast[i].get('win'), '风向'),
                     (forecast[i].get('level'), '风级'),
                     (forecast[i].get('temh'), '最高温'),
                     (forecast[i].get('teml'), '最低温'),
                     (forecast[i].get('wea'), '天气')]
            group = LabelFrame(root1, text='天气状况', padx=0, pady=0)  # 框架
            group.pack(padx=11, pady=0, side=LEFT)  # 放置框架
            for lang, value in LANGS:  # 将数据放入框架中
                c = Label(group, text=value + ': ' + lang)
                c.pack(anchor=W)
        Button(root1, text='确认并退出', width=10, command=root1.quit).place(x=500, y=230, width=80, height=40)  # 退出按钮
        root1.mainloop()

    # 布置按键
    Button(root, text="确认", width=10, command=get_weather_data) \
        .grid(row=3, column=0, sticky=W, padx=10, pady=5)
    Button(root, text='退出', width=10, command=root.quit) \
        .grid(row=3, column=1, sticky=E, padx=10, pady=5)
    if running == 1:
        root.mainloop()


if __name__ == "__main__":
    main()